package org.niux.aims.transition;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.niux.aims.common.util.SpringUtil;
import org.niux.aims.common.util.StringUtil;
import org.niux.aims.service.IAccountService;
import org.niux.aims.service.IApplicationService;
import org.niux.aims.service.IAuthService;
import org.niux.aims.service.ILogsService;
import org.niux.aims.vo.AccountVO;
import org.niux.aims.vo.ApplicationVO;
import org.niux.aims.vo.AuthVO;

/**
 * 
 * Copyright (c) 2009,niux<br>
 * All rights reserved.<br>
 * 
 * 文件名称：ServerListener.java<br>
 * 摘    要：服务监听类<br>
 * <br>
 * 当前版本：<br>
 * 作    者：铭显 Email: <a href="mailto:liangmingxian@gmail.com">liangmingxian@gmail.com</a><br>
 * 完成日期：@since 2013-9-25<br>
 * <br>
 * 取代版本：<br>
 * 原作者  ：<br>
 * 完成日期：@since Oct 22, 2009<br>
 */
public class ServerListener extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3509846890094666539L;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request,response);
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getParameter("action");
		
		SpringUtil.setServletContext(this.getServletContext());
		ILogsService logsService = (ILogsService)SpringUtil.getBean("logsService");
		String requestIp = getIpAddr(request);
		
		if("".equals(action) || action == null){ //非法请求
			setResponse(response,"{result:\""+StatusCode.FAILS+"\",reason:\""+StatusCode.ILLEGAL_REQUEST+"\"}");
			
			//获取请求内容
			StringBuffer requestContent = new StringBuffer();

			BufferedReader in = request.getReader();
			
			int i = in.read();
			
			while(i != -1){
				requestContent.append((char) i);
				i = in.read();
			}
			
			logsService.addLog("接收到来自" + requestIp + "的非法请求，请求内容为："+request.getQueryString());
			
		} else if(action.equals("login")){ //登录
			String name = request.getParameter("name");
			String password = request.getParameter("password");
			String app = request.getParameter("app");
			
			logsService.addLog("接收到来自" + requestIp + "的登录请求，登录名为：" + name + "，请求应用ID为：" + app);
			
			String rs = loginInterface(name,password,app);
			
			setResponse(response,rs);
		} else if(action.equals("getAuth")){ //获取权限
			String accountid = request.getParameter("accountid");
			logsService.addLog("接收到来自" + requestIp + "的获取权限的请求，请求账户ID为：" + accountid);
			String rs = getAuthInterface(Integer.parseInt(accountid));
			
			setResponse(response,rs);
		} else if(action.equals("addAccount")){ //新增账户
			String name = request.getParameter("name");
			String password = request.getParameter("password");
			String app = request.getParameter("app");
			
			logsService.addLog("接收到来自" + requestIp + "的新增账户的请求，新增账户名为：" + name + "，所属应用ID为："+ app);
			
			String rs = addAccountInterface(app,name,password);
			
			setResponse(response,rs);
		} else if(action.equals("updatePassword")) { //修改密码
			String accountid = request.getParameter("accountid");
			String password = request.getParameter("password");
			
			logsService.addLog("接收到来自" + requestIp + "的修改密码的请求，请求账户ID为：" + accountid);
			
			String rs = updatePassword(accountid,password);
			
			setResponse(response,rs); 
		} else if(action.equals("removeAccount")){ //删除账户
			String app = request.getParameter("app");
			String name = request.getParameter("name");
			
			logsService.addLog("接收到来自" + requestIp + "的删除账户的请求，删除名为：" + name + "的账户，所属应用ID为："+ app);
			
			String rs = removeAccountInterface(app,name);
			
			setResponse(response,rs);
		} else {
			setResponse(response,"{result:\""+StatusCode.FAILS+"\",reason:\""+StatusCode.ILLEGAL_REQUEST+"\"}");
			
			//获取请求内容
			StringBuffer requestContent = new StringBuffer();

			BufferedReader in = request.getReader();
			
			int i = in.read();
			
			while(i != -1){
				requestContent.append((char) i);
				i = in.read();
			}
			
			logsService.addLog("接收到来自" + requestIp + "的非法请求，请求内容为："+request.getQueryString());
		}
	}
	
	/**
	 * 
	 * 方法概述：登录接口
	 * 描述：登录接口
	 * @param name
	 * @param password
	 * 返回类型：void
	 * 修改人：梁铭显
	 * 修改时间：2013-9-25
	 */
	public String loginInterface(String name,String password,String app){
		SpringUtil.setServletContext(this.getServletContext());
		IAccountService accountService = (IAccountService)SpringUtil.getBean("accountService");
		
		List<AccountVO> accounts = accountService.findByNameAndApp(name, Integer.parseInt(app));
		
		if(accounts.isEmpty()){ //账户不存在
			return "{result:\""+StatusCode.FAILS+"\",reason:\""+StatusCode.WITHOUT_THIS_USER+"\"}";
		} else if(accounts.size() > 1){ //账户数据出错
			return "{result:\""+StatusCode.FAILS+"\",reason:\""+StatusCode.ACCOUNT_DATA_WRONG+"\"}";
		} else {
			for(AccountVO account : accounts){
				if(!account.getPassword().equals(StringUtil.MD5Encode(password))){ //密码错误
					return "{\"result\":\""+StatusCode.FAILS+"\",\"reason\":\""+StatusCode.PASSWORD_IS_WRONG+"\"}";
				} else {
					return "{result:\""+StatusCode.SUCCESS+"\",id:\""+account.getId()+"\"}";
					// TODO: 登录成功后应加入登录记录，作为后续其它操作的合法性判断
				}
			}
			
			return "{result:\""+StatusCode.FAILS+"\",reason:\""+StatusCode.UNKNOWN_ERROR+"\"}";
		}
	}
	
	/**
	 * 
	 * 方法概述：获取实体代码
	 * 描述：获取实体代码
	 * @param accountid
	 * @return
	 * 返回类型：String
	 * 修改人：梁铭显 
	 * 修改时间：2013-9-26
	 */
	public String getAuthInterface(int accountid){
		SpringUtil.setServletContext(this.getServletContext());
		IAuthService authService = (IAuthService)SpringUtil.getBean("authService");
		List<AuthVO> auths = authService.findByAccount(accountid);
		
		StringBuffer entityCodes = new StringBuffer();
		for (AuthVO authVO : auths) {
			entityCodes.append("\"" + authVO.getEntity().getEntityCode() + "\",");
		}
		
		String jsonStr = "{result:\""+StatusCode.SUCCESS+"\",entitysCode:[" + entityCodes.substring(0, entityCodes.length() - 1) + "]}";
		return jsonStr;
	}
	
	/**
	 * 
	 * 方法概述：新增账户接口
	 * 描述：新增账户接口
	 * @param appid
	 * @param name
	 * @param password
	 * @return
	 * 返回类型：String
	 * 修改人：梁铭显 
	 * 修改时间：2013-9-26
	 */
	public String addAccountInterface(String appid,String name,String password){
		SpringUtil.setServletContext(this.getServletContext());
		IApplicationService applicationService = (IApplicationService)SpringUtil.getBean("applicationService");
		
		ApplicationVO app = applicationService.findById(Integer.parseInt(appid));
		
		if(app == null || app.getId() == null){ //应用不存在
			return "{result:\""+StatusCode.FAILS+"\",reason:\""+StatusCode.WITHOUT_THIS_APP+"\"}";
		}
		
		AccountVO account = new AccountVO();
		
		account.setName(name);
		account.setPassword(password);
		
		ApplicationVO appVo = new ApplicationVO();
		appVo.setId(Integer.parseInt(appid));
		
		account.setApp(appVo);
		
		SpringUtil.setServletContext(this.getServletContext());
		IAccountService accountService = (IAccountService)SpringUtil.getBean("accountService");
		
		List<AccountVO> accounts = accountService.findByNameAndApp(name, Integer.parseInt(appid));
		
		if(!accounts.isEmpty()){ //账户已存在
			return "{result:\""+StatusCode.FAILS+"\",reason:\""+StatusCode.ACCOUNT_ALREADY_EXISTS+"\"}";
		} else {
			accountService.save(account);
			return "{result:\""+StatusCode.SUCCESS+"\"}";
		}
	}
	
	/**
	 * 
	 * 方法概述：修改密码
	 * 描述：修改密码
	 * @param accountid
	 * @param password
	 * @return
	 * 返回类型：String
	 * 修改人：梁铭显 
	 * 修改时间：2013-9-26
	 */
	public String updatePassword(String accountid,String password){
		SpringUtil.setServletContext(this.getServletContext());
		IAccountService accountService = (IAccountService)SpringUtil.getBean("accountService");
		
		AccountVO accountVo = accountService.findById(Integer.parseInt(accountid));
		
		if(accountVo == null){
			return "{result:\""+StatusCode.FAILS+"\",reason:\""+StatusCode.WITHOUT_THIS_USER+"\"}";
		} else {
			accountVo.setId(Integer.parseInt(accountid));
			accountVo.setPassword(password);
			
			accountService.updatePassword(accountVo);
			return "{result:\""+StatusCode.SUCCESS+"\"}";
		}
	}
	
	/**
	 * 
	 * 方法概述：删除账户
	 * 描述：删除账户
	 * @param appId
	 * @param name
	 * @return
	 * 返回类型：String
	 * 修改人：梁铭显 
	 * 修改时间：2013-11-12
	 */
	public String removeAccountInterface(String appId,String name){
		SpringUtil.setServletContext(this.getServletContext());
		IAccountService accountService = (IAccountService)SpringUtil.getBean("accountService");
		
		List<AccountVO> accountVos = accountService.findByNameAndApp(name, Integer.parseInt(appId));
		
		if(accountVos.isEmpty()){
			return "{result:\""+StatusCode.FAILS+"\",reason:\""+StatusCode.WITHOUT_THIS_USER+"\"}";
		} else {
			for(AccountVO accountVo : accountVos) {
				accountService.delete(accountVo.getId());
			}
			
			return "{result:\""+StatusCode.SUCCESS+"\"}";
		}
	}
	
	/**
	 * 
	 * 方法概述：获取请求IP
	 * 描述：获取请求IP
	 * @param request
	 * @return
	 * 返回类型：String
	 * 修改人：梁铭显
	 * 修改时间：2013-9-25
	 */
	private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 多次反向代理后会有多个IP值，第一个为真实IP。
        if (!"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
            if(ip.indexOf(",") > 0){
                return ip.substring(0,ip.indexOf(","));
            }else {
                return ip;
            }
        }
        return ip;
    }
	
	/**
	 * 
	 * 方法概述：设置返回内容
	 * 描述：设置返回内容
	 * @param response
	 * @param content
	 * @throws IOException
	 * 返回类型：void
	 * 修改人：梁铭显
	 * 修改时间：2013-9-25
	 */
	private void setResponse(HttpServletResponse response,String content) throws IOException{
		response.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		out.print(content);
		out.flush();
		out.close();
	}
}
